package com.example.mq.mqserver.core;

import lombok.Data;

import java.io.Serializable;
import java.util.UUID;

/**
 * 表示一个要传递的消息
 * 此处的Message需要能够在网络中传输,并且也需要写入文件
 * 此时就需要针对 Message 进行序列化和反序列化
 * 此处使用 标准库 中的序列化/返序列化操作(Serializable 接口)
 */
@Data
public class Message implements Serializable {

    //属性部分
    private BasicProperties basicProperties=new BasicProperties();
    //正文部分
    private byte[] body;
    //辅助用的属性
    //Message 后续会存储到文件中 (如果持久化的化)
    //一个文件会存储很多消息.如果找到某个消息在文件中的具体位置呢？
    //使用下面的两个偏移量来表示  [offsetBeg,offsetEnd)
    //这俩属性并不需要被序列号保存到文件中 因为消息一旦保存到文件中 所在的位置就固定了 并不需要单独存储
    //这俩属性存在的主要目的 主要是让内存中的 Message 对象 能够快速找到对应硬盘上的 Message 的位置

    private transient long offsetBeg=0;  //表示数据的开头距离文件开头的位置
    private transient long offsetEnd=0; //表示数据的结尾距离文件开头的位置
    //使用这个属性 表示该消息在文件中是否是有效消息 (针对文件中的消息,如果删除,使用逻辑删除)
    //0x1 表示有效 0x0表示无效
    private byte isValid=0x1;

    //方便在Message中直接调用basicProperties中的属性的方法
    public String getMessageId(){
        return basicProperties.getMessageId();
    }
    public void setMessageId(String messageId){
        basicProperties.setMessageId(messageId);
    }
    public String getRoutingKey(){
        return basicProperties.getRoutingKey();
    }
    public void setRoutingKey(String routingKey){
       basicProperties.setRoutingKey(routingKey);
    }
    public void setDeliverMode(int deliverMode){
        basicProperties.setDeliverMode(deliverMode);
    }
    public int getDeliverMode(){
        return basicProperties.getDeliverMode();
    }
    //创建一个工厂方法,让工厂方法帮我们封装一下创建Message对象的过程
    //这个方法中创建的 Message 对象,会生成唯一的id
    public static Message  createMessageWitId(String routingKey,BasicProperties basicProperties,byte[] body){
        Message message=new Message();
        if(basicProperties!=null){
            message.setBasicProperties(basicProperties);
        }
        message.setRoutingKey(routingKey);
        //此处生成的MessageId 以M-作为前缀.
        message.setMessageId("M-"+ UUID.randomUUID());

        message.body=body;
        //此处是把basicProperties和body先设置出来 这俩是核心内容
        //其他属性是持久化的时候需要用到的 此处只是在内存中创建对象,后面在文件中存储时才会用到
        return message;
    }
}
